﻿using System;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Carbon.Web.Forms.jQueryForms
{
    public class DropDownListEditor : DropDownList, IEditor, IScriptControl
    {
		#region Classes (1)
		private class DropDownListEditorScriptDescriptor : ScriptDescriptor
        {
			#region Fields (1)
			private DropDownListEditor m_Editor = default(DropDownListEditor);
			#endregion

			#region Properties (1)
			public DropDownListEditor Editor
            {
                get
                {
                    return m_Editor;
                }
            }
			#endregion

			#region Constructors (1)
			public DropDownListEditorScriptDescriptor(DropDownListEditor editor)
                : base()
            {
                if (editor == null) throw new ArgumentNullException("editor");

                this.m_Editor = editor;
            }
			#endregion

			#region Methods (1)

			protected override string GetScript()
            {
                return Editor.GetClientScript();
            }

			#endregion
        }
		#endregion

		#region Fields (2)
		private IDropDownListItemCollection m_Items = default(IDropDownListItemCollection);

		private ListEditor m_Parent = default(ListEditor);
		#endregion


		#region Properties (5)
		public IDropDownListItemCollection DataItems
        {
            get
            {
                return m_Items;
            }
            private set
            {
                m_Items = value;

                if (m_Items == null) throw new NullReferenceException("m_Items");

                base.Items.Clear();

                if (m_Items.CanSelectNull)
                {
                    base.Items.Add(new ListItem("", ""));
                }

                int ordinal = 0;
                foreach (IListEditorItem item in m_Items)
                {
                    base.Items.Add(new ListItem(m_Items.GetDisplayName(item.Data), ConvertInvariant.ToString(ordinal++)) { Selected = false });
                }

                if (m_Items.SelectedIndex != null)
                    this.SelectedIndex = m_Items.CanSelectNull ? m_Items.SelectedIndex.Value + 1 : m_Items.SelectedIndex.Value;
            }
        }
		public bool IsNull
        {
            get
            {
                return ((IDropDownListItemCollection)Value).SelectedIndex == null;
            }
        }
		public new ListEditor Parent
        {
            get
            {
                return m_Parent;
            }
        }
		public bool ReadOnly
        {
            get
            {
                return !this.Enabled;
            }
            set
            {
                this.Enabled = !value;
            }
        }
		public object Value
        {
            get
            {
                return DataItems;
            }
            set
            {
                DataItems = (IDropDownListItemCollection)value;
            }
        }
		#endregion

		#region Constructors (1)
		public DropDownListEditor(IDropDownListItemCollection items, ListEditor parent)
            : base()
        {
            if (items == null) throw new ArgumentNullException("items");
            if (parent == null) throw new NullReferenceException("parent");

            this.DataItems = items;
            this.m_Parent = parent;
        }
		#endregion

		#region ASP Processing

		protected override bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
        {
            base.LoadPostData(postDataKey, postCollection);
            int? previousIndex = DataItems.SelectedIndex;

            ReturnDataFromInterface();

            if (previousIndex != DataItems.SelectedIndex)
            {
                if (this.AutoPostBack)
                {
                    DataItems.SelectedIndex = previousIndex;
                    return true;
                }
            }

            return false;
        }

		protected override void RaisePostDataChangedEvent()
        {
            base.RaisePostDataChangedEvent();
            ReturnDataFromInterface();

            if (this.Parent.AutoPostback)
            {
                this.RaiseBubbleEvent(this, new UpdateModelEventArgs());
            }
        }

		protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            Parent.ScriptManager.RegisterScriptControl(this);
            Parent.ScriptManager.RegisterScriptDescriptors(this);
            
            this.CssClass = InternalUtility.MergeCssClasses(Constants.DropDownClass, Parent.CssClass);
            this.Width = Parent.Width;
        }

		#endregion

		#region Methods (5)

		protected virtual String GetClientScript()
        {
            return string.Format("Carbon.Web.Forms.jQueryForms.DropDown(\"{0}\", {1});", this.ClientID, ConvertInvariant.ToString(this.Parent.CanBeNull).ToLower());
        }

		public virtual IEnumerable<ScriptDescriptor> GetScriptDescriptors()
        {
            return new ScriptDescriptor[] { new DropDownListEditorScriptDescriptor(this) };
        }

		public virtual IEnumerable<ScriptReference> GetScriptReferences()
        {
            return new ScriptReference[] { };
        }

		/// <summary>
        /// Very important overload, otherwise bad things happen. (hint: cachedSelectedIndex, wtf.)
        /// </summary>
        /// <param name="dataSource"></param>
        protected override void PerformDataBinding(System.Collections.IEnumerable dataSource)
        {

        }

		private void ReturnDataFromInterface()
        {
            int index = this.SelectedIndex;

            if (m_Items.CanSelectNull)
            {
                index -= 1;
            }

            if (index < 0)
                m_Items.SelectedIndex = null;
            else
                m_Items.SelectedIndex = index;
        }

		#endregion
    }
}
